package openmips.unittests

import chisel3._
import chisel3.util._
import chisel3.iotesters._
import org.scalatest.{Matchers, FlatSpec}

import openmips.id.Regfile

class RegfileTester(dut: Regfile) extends PeekPokeTester(dut) {
    // test reg zero
    poke(dut.io.write.addr, 0.U)
    poke(dut.io.write.data, 1.U)
    poke(dut.io.write.enable, true.B)
    step(1)

    poke(dut.io.read(1).addr, 0.U)
    poke(dut.io.read(1).enable, true.B)
    expect(dut.io.read(1).data, 0.U)
    step(1)
    // test write then read
    for (i <- 1 to 31) {
        poke(dut.io.write.addr, i.U)
        poke(dut.io.write.data, i.U)
        poke(dut.io.write.enable, true.B)
        step(1)

        poke(dut.io.read(1).addr, i.U)
        poke(dut.io.read(1).enable, true.B)
        expect(dut.io.read(1).data, i.U)
    }
    // test only read
    for (i <- 1 to 31) {
        poke(dut.io.read(1).addr, i.U)
        poke(dut.io.read(1).enable, true.B)
        expect(dut.io.read(1).data, i.U)
    }
    step(1)
    // test write while read
    for (i <- 1 to 31) {
        poke(dut.io.write.addr, i.U)
        poke(dut.io.write.data, (i * 2).U)
        poke(dut.io.write.enable, true.B)

        poke(dut.io.read(1).addr, i.U)
        poke(dut.io.read(1).enable, true.B)
        expect(dut.io.read(1).data, (i * 2).U)
        step(1)
    }
}

class RegfileSpec extends FlatSpec with Matchers {
    behavior of "Regfile"

    it should "behave correctly" in {
        chisel3.iotesters.Driver(() => new Regfile) { c =>
            new RegfileTester(c)
        } should be(true)
    }
}